#include "stdafx.h"
#include "DirectInput8Hijack.h"
#include "../../Common/PluginManager/PluginManager.h"
#include "../../Common/Interfaces/IEnvironment.h"
#include "../../Common/Interfaces/IUserInterface.h"


k_DirectInput8Hijack* k_DirectInput8Hijack::instance = NULL;
DefineHijack(k_DirectInput8Hijack, SetCooperativeLevel);
DefineHijack(k_DirectInput8Hijack, CreateDevice);
DefineHijack(k_DirectInput8Hijack, GetDeviceState);

HRESULT k_DirectInput8Hijack::SetCooperativeLevelReplacement(IDirectInputDevice8* self, HWND hwnd, DWORD level)
{
	PrintLog(ls_LogFile, L"DI8: SetCooperativeLevel\n");

	if(level & DISCL_EXCLUSIVE)
	{
		PrintLog(ls_LogFile, L"DI8: You want exclusive access? I don't think so!\n");
		level &= ~DISCL_EXCLUSIVE;
		level |= DISCL_NONEXCLUSIVE;
	}

	return SetCooperativeLevelReal(self, hwnd, level);	
}


HRESULT k_DirectInput8Hijack::CreateDeviceReplacement(IDirectInput8* self, REFGUID rguid, LPDIRECTINPUTDEVICE *lplpDirectInputDevice, LPUNKNOWN pUnkOuter)
{
	PrintLog(ls_LogFile, L"DI8: Init Device Hooks\n");

	LPDIRECTINPUTDEVICE device;
	HRESULT result = CreateDeviceReal(self, rguid, &device, pUnkOuter);

	PerformHijack(device, SetCooperativeLevel);
	PerformHijack(device, GetDeviceState);

	*lplpDirectInputDevice = device;
	return result;
}

HRESULT k_DirectInput8Hijack::GetDeviceStateReplacement(IDirectInputDevice8* self, DWORD cbData, LPVOID lpvData)
{
	return GetDeviceStateReal(self, cbData, lpvData);
}

k_DirectInput8Hijack::k_DirectInput8Hijack()
	: mb_Initialized(false)
{
	
}


k_DirectInput8Hijack::~k_DirectInput8Hijack()
{
}


void* k_DirectInput8Hijack::QueryInterface(const GUID& ar_InterfaceGuid)
{
	if (ar_InterfaceGuid == __uuidof(IDirectInputHijack)) 
		return static_cast<IDirectInputHijack*>(this);
	else if (ar_InterfaceGuid == __uuidof(IService)) 
		return static_cast<IService*>(this);

	return NULL; 
}


void k_DirectInput8Hijack::Initialize(IServiceLocator& ar_ServiceLocator)
{
	instance = this;
	mb_Initialized = true;

	IEnvironment& lr_Environment = object_cast<IEnvironment>(ar_ServiceLocator);
	ls_LogFile = lr_Environment.get_ModulePath()+L"Walhall.log";

	PrintLog(ls_LogFile, L"DI8: Init Hooks\n");

	LPDIRECTINPUT8  directInput8; 
	DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
		IID_IDirectInput8, (void**)&directInput8, NULL); 

	PerformHijack(directInput8, CreateDevice);
}


void k_DirectInput8Hijack::Deinitialize()
{
	ReleaseHijack(CreateDevice);
	ReleaseHijack(SetCooperativeLevel);
	mb_Initialized = false;
}


bool k_DirectInput8Hijack::get_IsInitialized() const
{
	return mb_Initialized;
}
